package com.panda.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.panda.annotation.SystemLog;
import com.panda.entity.po.User;
import com.panda.entity.vo.*;
import com.panda.enums.AppHttpCodeEnum;
import com.panda.mapper.UserMapper;
import com.panda.service.ArticleService;
import com.panda.service.UserService;
import com.panda.service.VideoService;
import com.panda.utils.BeanCopyUtil;
import com.panda.utils.RedisCache;
import com.panda.utils.RespondResult;
import com.panda.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.panda.utils.DataFormatUtil.*;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.panda.utils.DataFormatUtil.twoDimensionListSort;

/**
 * (User)表服务实现类
 *
 * @author makejava
 * @since 2022-03-13 10:29:17
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final RedisCache redisCache;

    private final PasswordEncoder passwordEncoder;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    public UserServiceImpl(RedisCache redisCache, PasswordEncoder passwordEncoder) {
        this.redisCache = redisCache;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    @SystemLog(businessName = "注册")
    public RespondResult register(RegisterVo registerVo) {

        //用户存在
        if (usernameExist(registerVo.getUsername())) {
            return RespondResult.errorResult(AppHttpCodeEnum.USERNAME_EXIST);
        }

        // 通过图片验证码编号获取,图片验证码
        String captcha = redisCache.getCacheObject("captcha:" + registerVo.getCaptchaId());
        //判断图片验证码是否过期
        if (captcha == null || captcha.isEmpty()) {
            return RespondResult.errorResult(AppHttpCodeEnum.CAPTCHA_NOT_FOUND);
        }
        // 判断图片验证码是否正确
        if (!captcha.equals(registerVo.getCaptchaCode())) {
            return RespondResult.errorResult(AppHttpCodeEnum.CAPTCHA_ERROR);
        }
        // 删除redis中的图片验证码
        redisCache.deleteObject("captcha:" + registerVo.getCaptchaId());
        String encode = passwordEncoder.encode(registerVo.getPasswordHash());
        User user = new User();
        user.setUsername(registerVo.getUsername());
        user.setPasswordHash(encode);
        save(user);
        return RespondResult.okResult(200, "注册成功, 请重新登陆");
    }


    @Override
    public RespondResult<UserInfoVo> getUserInfo(Long id) {
        User user = getById(id);
        if (user != null) {
            UserInfoVo userInfoVo = BeanCopyUtil.copyBean(user, UserInfoVo.class);
            return RespondResult.okResult(userInfoVo);
        }
        return RespondResult.errorResult(AppHttpCodeEnum.USER_NOTFOUND);
    }

    @Override
    @SystemLog(businessName = "更新用户信息")
    public RespondResult<ModifyUserVo> updateUserInfo(ModifyUserVo userVo) {

        Long userId;
        try {
            userId = SecurityUtils.getUserId();
        } catch (Exception e) {
            return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);
        }

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);
        updateWrapper.set(Objects.nonNull(userVo.getSex()), User::getSex, userVo.getSex());
        updateWrapper.set(Objects.nonNull(userVo.getAvatar()), User::getAvatar, userVo.getAvatar());
        updateWrapper.set(Objects.nonNull(userVo.getDetail()), User::getDetail, userVo.getDetail());

        boolean update = update(updateWrapper);

        userVo.setId(userId);
        if (update) {
            return RespondResult.okResult(userVo);

        }
        return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);
    }

    /**
     * 修改用户性别（管理后台）
     *
     * @param user
     * @return
     */
    @Override
    public RespondResult updateUserSex(User user) {
        User user1 = getById(user.getId());
        if (user1 != null) {
            user1.setSex(user.getSex());
            updateById(user1);
            return RespondResult.okResult();
        }
        return RespondResult.errorResult(404, "用户不存在");
    }

    /**
     * 更新管理后台用户的头像
     *
     * @param user
     * @return
     */
    @Override
    public RespondResult updateUserAvatar(User user) {
        User user1 = getById(user.getId());
        if (user1 != null) {
            user1.setAvatar(user.getAvatar());
            updateById(user1);
            return RespondResult.okResult();
        }
        return RespondResult.errorResult(404, "用户不存在");
    }

    /**
     * 统计一周内得用户注册情况
     *
     * @return
     */
    @Override
    public RespondResult registerCount() {
        List<Map<String, String>> mapList = createdUserStatistic();
        List<LinkedList<String>> linkedList = twoDimensionListSort(mapList);
        return RespondResult.okResult(linkedList);
    }

    @Override
    public List<Map<String, String>> createdUserStatistic() {
        return userMapper.createdUserStatistic();
    }

    @Override
    public RespondResult updatePassword(UserPwdVo userPwdVo) {

        Long userId;
        try {
            userId = SecurityUtils.getUserId();
        } catch (Exception e) {
            return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);
        }

        boolean matches = passwordEncoder.matches(userPwdVo.getOldPwd(), getById(userId).getPasswordHash());
        if (!matches) {
            return RespondResult.errorResult(AppHttpCodeEnum.ORIGIN_PWD_ERROR);
        }

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);
        updateWrapper.set(User::getPasswordHash, passwordEncoder.encode(userPwdVo.getNewPwd()));

        boolean update = update(updateWrapper);

        if (update) {
            return RespondResult.okResult();
        }
        return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);

    }


    @Override
    public RespondResult updateUsername(UserVo userVo) {

        Long userId;
        try {
            userId = SecurityUtils.getUserId();
        } catch (Exception e) {
            return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);
        }

        //用户存在
        if (usernameExist(userVo.getUsername())) {
            return RespondResult.errorResult(AppHttpCodeEnum.USERNAME_EXIST);
        }

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userId);
        updateWrapper.set(User::getUsername, userVo.getUsername());

        boolean update = update(updateWrapper);
//        userVo.setId(userId);

        if (update) {
            return RespondResult.okResult(userVo);
        }
        return RespondResult.errorResult(AppHttpCodeEnum.MODIFY_USER_ERROR);

    }

    private boolean usernameExist(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper) != null;
    }
}

